const http = require('http');
const https = require('https');
const unzipper = require('unzipper');

function auth(request, response) {
  const query = new URLSearchParams(request.url.match(/^\/auth\?([\s\S]+)$/)[1]);
  getToken(query.get('code'), info => {
    response.write(`<a href="http://localhost:8001/?token=${info.access_token}">publish</a>`)
    response.end();
  });
}

function getUser(token, callback) {
  console.log(token);
  const request = new https.request({
    hostname: 'api.github.com',
    path: '/user',
    port: 443,
    method: 'GET',
    headers: {
      Authorization: 'token ' + token,
      'User-Agent': 'star-x-publish-tool',
      Accept: 'application/vnd.github.v3+json',
    },
  }, function (response) {
    let body = '';

    response.on('data', data => {
      body += data.toString();
    });

    response.on('end', () => {
      callback(JSON.parse(body));
    });
  });
  request.end();
}

function getToken(code, callback) {
  const request = new https.request({
    hostname: 'github.com',
    path: `/login/oauth/access_token?code=${code}&client_id=Iv1.efb0c1bedf337e41&client_secret=9a495490cfee5b25971c71cb8923511910118ef3`,
    port: 443,
    method: 'POST',
  }, function (response) {
    let body = '';

    response.on('data', data => {
      body += data.toString();
    });

    response.on('end', () => {
      callback(Object.fromEntries(new URLSearchParams(body).entries()));
    });
  });
  request.end();
}

function publish(request, response) {
  const query = new URLSearchParams(request.url.match(/\?([\s\S]+)$/)[1]);
  getUser(query.get('token'), info => {
    if (info.login === 'jackandjohn') {
      const stream = unzipper.Extract({
        path: '../server/public',
      });

      const pipe = request.pipe(stream);

      pipe.on('finish', () => {
        stream.destroy();
        response.end('Success');
      });
    } else {
      response.end('Failed');
    }
  });
}

const server = http.createServer(function (request, response) {
  if (request.url.match(/^\/auth\?/)) {
    return auth(request, response);
  }

  if (request.url.match(/^\/publish\?/)) {
    return publish(request, response);
  }
});

server.listen(8000);